//////////////////////////////////////////////////
// EASIM project
// easim.net.Clock
// 2007/6/6 2:14 PM
// Cong Liu
// gzcong@gmail.com

// Copyright (C) 2007
// All rights reserved.
// Refer to LICENSE of JIST (Java In Simulation Time) for terms and conditions of use.

package easim.net;

import jist.runtime.JistAPI;
import java.util.HashMap;

public class Clock
{

  protected static HashMap timers = new HashMap(); // Timer:int[]
  protected static TimerEntity timerEntity = new TimerEntity();

  public static long getTime() {
    return JistAPI.getTime();
  }

  public static boolean start(Timer timer, long delay, boolean cancelPrevTimer) {
    int[] timerData = (int[])timers.get(timer);
    if (timerData == null) {
      timerData = new int[2];
      timerData[0] = 1;
      timerData[1] = 1;
    }
    else {
      if (timerData[0] % 2 == 0) {
        ++ timerData[0];
        ++ timerData[1];
      }
      else {
        if (! cancelPrevTimer) return false;
        timerData[0] += 2;
        ++ timerData[1];
      }
    }
    timers.remove(timer);
    timers.put(timer, timerData);
    timerEntity.start(timer, delay, timerData[0]);
    return true;
  }

  public static boolean cancel(Timer timer) {
    int[] timerData = (int[])timers.get(timer);
    if (timerData == null) {
      return false;
    }
    else {
      if (timerData[0] % 2 == 0) {
        return false;
      }
      else {
        ++ timerData[0];
        return true;
      }
    }
  }

  protected static class TimerEntity implements JistAPI.Entity
  {
    public void start(Timer timer, long delay, int tId) {
      JistAPI.sleep(delay);
      timeout(timer, tId);
    }
    public void timeout(Timer timer, int tId) {
      int[] timerData = (int[])timers.get(timer);
      -- timerData[1];
      if (timerData[1] <= 0) {
        timers.remove(timer);
      }
      if (tId == timerData[0]) {
        ++ timerData[0];
        timer.timeout();
      }
    }
  }

}
